package com.woniuxy.yoga.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.yoga.admin.dao.mapper.AdminRoleMapper;
import com.woniuxy.yoga.admin.dao.mapper.RoleResourceMapper;
import com.woniuxy.yoga.admin.dao.model.AdminRole;
import com.woniuxy.yoga.admin.dao.model.Resource;
import com.woniuxy.yoga.admin.dao.mapper.ResourceMapper;
import com.woniuxy.yoga.admin.dao.model.RoleResource;
import com.woniuxy.yoga.admin.model.dto.resource.RoleResourceDTO;
import com.woniuxy.yoga.admin.model.exception.AdminException;
import com.woniuxy.yoga.admin.model.exception.AdminExceptionCode;
import com.woniuxy.yoga.admin.model.param.resource.AddResourceParam;
import com.woniuxy.yoga.admin.model.param.resource.CancelResourceRelationParam;
import com.woniuxy.yoga.admin.model.param.resource.ReResourceRelationParam;
import com.woniuxy.yoga.admin.model.param.resource.SelectResourcePageParam;
import com.woniuxy.yoga.admin.service.ResourceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.statedata.AdminState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 资源表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements ResourceService {

    @Autowired
    private ResourceMapper resourceMapper;
    @Autowired
    private AdminRoleMapper adminRoleMapper;
    @Autowired
    private RoleResourceMapper roleResourceMapper;
    /**
     * 通过资源ID集合查询资源集合
     * @param resourceIds
     * @return
     */
    @Override
    public List<Resource> selectResourceByIds(List<Integer> resourceIds) {
        List<Resource> resources = resourceMapper.selectBatchIds(resourceIds);
        return resources;
    }

    /**
     * 新增管理员资源权限
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addResource(AddResourceParam param) {
        //查询资源名是否重复
        LambdaQueryWrapper<Resource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resource::getResourceName,param.getResourceName());
        Resource resource = resourceMapper.selectOne(wrapper);
        if (resource!=null) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_RESOURCENAME_REPEAT);
        }
        //查询资源路径是否重复
        LambdaQueryWrapper<Resource> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Resource::getResourcePath,param.getResourcePath());
        Resource resourcePath = resourceMapper.selectOne(queryWrapper);
        if (resourcePath!=null) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_RESOURCEPATH_REPEAT);
        }
        //新增数据库资源表
        Resource newResource = BeanUtil.toBean(param, Resource.class);
        resourceMapper.insertResource(newResource);
        //新增角色资源关系表
        QueryWrapper<AdminRole> adminRoleQueryWrapper = new QueryWrapper<>();
        List<AdminRole> adminRoles = adminRoleMapper.selectList(adminRoleQueryWrapper);
        for (AdminRole adminRole : adminRoles) {
            RoleResource roleResource = new RoleResource();
            roleResource.setResourceId(newResource.getResourceId());
            roleResource.setRoleId(adminRole.getRoleId());
            //若为高级管理员则默认拥有资源权限
            if (adminRole.getRoleId()== AdminState.HIGHTER_ADMIN) {
                roleResource.setRelationState(AdminState.ROLE_RELATION_STATE_RIGHT);
            }else {//若为普通管理员则默认不拥有新资源的权限
                roleResource.setRelationState(AdminState.ROLE_RELATION_STATE_NO_RIGHT);
            }
            roleResourceMapper.insert(roleResource);
        }
    }

    /**
     * 分页查询角色资源
     * @param param
     * @return
     */
    @Override
    public PageInfo selectResourceByRole(SelectResourcePageParam param) {
        //查询该角色是否存在
        AdminRole adminRole = adminRoleMapper.selectById(param.getRoleId());
        if (adminRole==null) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ROLE_NOTEXISTS);
        }
        //查询角色资源关联表
        LambdaQueryWrapper<RoleResource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleResource::getRoleId,param.getRoleId());
        //开始分页
        Page<RoleResource> page = new Page<>(param.getCurrent()==null?1:param.getCurrent(),param.getSize()==null?5:param.getSize());
        roleResourceMapper.selectPage(page,wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        //对象转换
        List<RoleResourceDTO> roleResourceDTOS = new ArrayList<>();
        for (RoleResource roleResource : page.getRecords()) {
            RoleResourceDTO roleResourceDTO = BeanUtil.toBean(roleResource, RoleResourceDTO.class);
            roleResourceDTO.setRoleName(adminRole.getRoleName());
            Resource resource = resourceMapper.selectById(roleResource.getResourceId());
            System.out.println(resource);
            roleResourceDTO.setResourceName(resource.getResourceName());
            roleResourceDTO.setResourcePath(resource.getResourcePath());
            roleResourceDTOS.add(roleResourceDTO);
        }
        //分页参数赋值
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(roleResourceDTOS);
        return pageInfo;
    }

    /**
     * 取消角色资源关联
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelResourceRelation(CancelResourceRelationParam param) {
        //查询该角色是否存在
        AdminRole adminRole = adminRoleMapper.selectById(param.getRoleId());
        if (adminRole==null) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ROLE_NOTEXISTS);
        }
        //高级管理员不能被操作
        if (adminRole.getRoleId()== AdminState.HIGHTER_ADMIN) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_HIGHERADMIN_PROTECT);
        }
        //查询角色资源关联表
        LambdaQueryWrapper<RoleResource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleResource::getRoleId,param.getRoleId()).eq(RoleResource::getResourceId,param.getResourceId());
        RoleResource roleResource = roleResourceMapper.selectOne(wrapper);
        //查看是否存在此资源
        if (roleResource==null) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_RESOURCE_NOTHAING);
        }
        //查看关联状态是否是已关联
        if (roleResource.getRelationState()== AdminState.ROLE_RELATION_STATE_NO_RIGHT) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_RELATION_STATEERROR);
        }
        //修改关联状态为未关联
        roleResource.setRelationState(AdminState.ROLE_RELATION_STATE_NO_RIGHT);
        roleResourceMapper.updateById(roleResource);
    }

    /**
     * 取得该资源权限
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void ReResourceRelation(ReResourceRelationParam param) {
        //查询该角色是否存在
        AdminRole adminRole = adminRoleMapper.selectById(param.getRoleId());
        if (adminRole==null) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ROLE_NOTEXISTS);
        }
        //高级管理员不能被操作
        if (adminRole.getRoleId()== AdminState.HIGHTER_ADMIN) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_HIGHERADMIN_PROTECT);
        }
        //查询角色资源关联表
        LambdaQueryWrapper<RoleResource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleResource::getRoleId,param.getRoleId()).eq(RoleResource::getResourceId,param.getResourceId());
        RoleResource roleResource = roleResourceMapper.selectOne(wrapper);
        //查看是否存在此资源
        if (roleResource==null) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_RESOURCE_NOTHAING);
        }
        //查看关联状态是否是已关联
        if (roleResource.getRelationState()!= AdminState.ROLE_RELATION_STATE_NO_RIGHT) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_RELATION_STATEERROR);
        }
        //修改关联状态为已关联
        roleResource.setRelationState(AdminState.ROLE_RELATION_STATE_RIGHT);
        roleResourceMapper.updateById(roleResource);
    }

}
